#include "acceptor.h"
#include "event_loop.h"
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <unistd.h>

namespace {
void setNonBlocking(int fd) {
    int flags = ::fcntl(fd, F_GETFL, 0);
    ::fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
}

Acceptor::Acceptor(EventLoop& loop, int listenFd)
    : EventHandler(loop, listenFd) {
    setNonBlocking(listenFd);
}

void Acceptor::handleEvent(uint32_t events) {
    if (!(events & EPOLLIN)) return;

    while (true) {
        int connFd = ::accept4(fd(), nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
        if (connFd == -1) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                break;  // 已无更多可读连接
            }
            return;
        }

        if (newConnectionCallback_) {
            newConnectionCallback_(connFd);  // 交给上层选择 sub-loop
        } else {
            ::close(connFd);
        }
    }
}